home *** CD-ROM | disk | FTP | other *** search
/ Chip 2011 November / CHIP_2011_11.iso / Programy / Inne / Gry / Carnage_Contest / scripts / CC Original / movement / Rope.lua < prev    next >
Text File  |  2010-09-29  |  12KB  |  376 lines

  1. --------------------------------------------------------------------------------
  2. -- Really Unoptimized Rope
  3. -- Tobchen Carnage Contest Weapon
  4. -- Script by Tobchen, August 2010, www.tobchen.de
  5. --------------------------------------------------------------------------------
  6.  
  7. --[[
  8. CHANGES BY DC August/September 2010:
  9. - attack key for shooting and releasing
  10. - forceframe command activated
  11. - playercollision activated
  12. - impact fx disabled
  13. - item amount is decreased on use (first shot)
  14. - rope disappears when terrain changes (e.g. mine explosion)
  15. ]]
  16.  
  17. -- Setup Tables
  18. if cc == nil then cc = {} end
  19. cc.rope = {}
  20.  
  21.  
  22. -- Some things
  23. cc.rope.stack = {} -- The stack contains every rope-terrain-collision-point
  24. cc.rope.stack_top = 0
  25. cc.rope.len = 0
  26. cc.rope.left = 0
  27. cc.rope.rot = 0
  28. cc.rope.max_len = 400 -- I really think it's not wise to increase that one
  29. cc.rope.dir = 0
  30. cc.rope.speed = 0
  31.  
  32. -- Load & Prepare Ressources
  33. cc.rope.gfx_icon = loadgfx("weapons/ropeicon.png")
  34. setmidhandle(cc.rope.gfx_icon)
  35. cc.rope.gfx_arms = loadgfx("weapons/ropearms.png")
  36. setmidhandle(cc.rope.gfx_arms)
  37.  
  38. --------------------------------------------------------------------------------
  39. -- Weapon: Unfinished Ninja Rope
  40. --------------------------------------------------------------------------------
  41.  
  42. cc.rope.id=addweapon("cc.rope", "Rope (experimental! bugs!)", cc.rope.gfx_icon,1,0) -- Add Weapon (1 use, first in round 0)
  43.  
  44. -- Draw
  45. function cc.rope.draw()
  46.     -- Draw crosshair
  47.     if weapon_mode == 0 then
  48.         -- FOR KEYBOARD-AIMING:
  49.         hudcrosshair(0, 0)
  50.         hudinfo("Press [fire] to shoot the rope, press [fire] again to release!")
  51.     -- Draw the rope
  52.     elseif weapon_mode == 1 then
  53.         setblend(blend_alpha)
  54.         setalpha(1)
  55.         setcolor(200, 200, 200)
  56.         drawline(getplayerx(0), getplayery(0), cc.rope.stack[cc.rope.stack_top].x, cc.rope.stack[cc.rope.stack_top].y, 2)
  57.         if cc.rope.stack_top > 1 then
  58.             for i=1, cc.rope.stack_top-1, 1 do
  59.                 drawline(cc.rope.stack[i].x, cc.rope.stack[i].y, cc.rope.stack[i+1].x, cc.rope.stack[i+1].y, 2)
  60.             end
  61.         end
  62.         setrotation(0)
  63.         setscale(1, 1)
  64.         setcolor(255, 255, 255)
  65.         -- No player animation, but new arms
  66.         playerforceframe(0, 2)
  67.         drawimage(cc.rope.gfx_arms, getplayerx(0), getplayery(0)+3)
  68.     end
  69. end
  70.  
  71. -- Attack
  72. function cc.rope.attack(attack)
  73.     -- // CHANGE BY DC: Disable rope with space (requires a timer)
  74.     if weapon_timer>0 then weapon_timer=weapon_timer-1 end
  75.     -- CHANGE BY DC //
  76.  
  77.     -- FOR MOUSE-AIMING:
  78.     --hudpositioning(pos_invisible)
  79.     
  80.     -- FOR MOUSE-AIMING:
  81.     --if (weapon_position == 1) then
  82.     -- FOR KEYBOARD-AIMING:
  83.     
  84.     -- // CHANGE BY DC: Disable rope with space (requires a timer)
  85.     --if (weapon_mode == 0 and attack == 1) then
  86.     if (weapon_mode == 0 and attack == 1 and weapon_timer<=0) then
  87.     -- CHANGE BY DC //
  88.     
  89.         -- Is it a hit?
  90.         -- FOR MOUSE-AIMING:
  91.         --go_x = math.sin(math.rad(math.deg(math.atan2(getplayery(0)-weapon_y, getplayerx(0)-weapon_x))-90))
  92.         --go_y = -math.cos(math.rad(math.deg(math.atan2(getplayery(0)-weapon_y, getplayerx(0)-weapon_x))-90))
  93.         -- FOR KEYBOARD-AIMING:
  94.         go_x = math.sin(math.rad(getplayerrotation(0)))
  95.         go_y = -math.cos(math.rad(getplayerrotation(0)))
  96.         okay = 1
  97.         for i=7, cc.rope.max_len, 5 do
  98.             tmp_x = getplayerx(0)+(go_x*i)
  99.             tmp_y = getplayery(0)+(go_y*i)
  100.             if collision(col5x5, tmp_x, tmp_y, 1, 1, 1, 0) == 1 then
  101.                 for j=(i-2), i+2, 1 do
  102.                     tmp_x = getplayerx(0)+(go_x*j)
  103.                     tmp_y = getplayery(0)+(go_y*j)
  104.                     if collision(col1x1, tmp_x, tmp_y, 1, 1, 1, 0) == 1 then
  105.                         -- No more player control
  106.                         playercontrol(0)
  107.                         weapon_mode = 1
  108.                         -- // CHANGE BY DC: Decrease amount (use weapon)
  109.                         if weapon_shots==0 then useweapon(1) end
  110.                         -- CHANGE BY DC //
  111.                         weapon_shots = weapon_shots + 1
  112.                         -- Go
  113.                         cc.rope.stack_top = 0
  114.                         cc.rope.stack = {}
  115.                         cc.rope.stack_push(tmp_x, tmp_y, 0, 0)
  116.                         cc.rope.len = j
  117.                         cc.rope.left = j
  118.                         -- FOR MOUSE-AIMING:
  119.                         --cc.rope.rot = cc.rope.normangle(math.deg(math.atan2(getplayery(0)-weapon_y, getplayerx(0)-weapon_x))+90)
  120.                         -- FOR KEYBOARD-AIMING:
  121.                         cc.rope.rot = cc.rope.normangle(-getplayerdirection(0)*(180-math.abs(getplayerrotation(0))))
  122.                         
  123.                         tmp_angle = cc.rope.normangle(math.deg(math.atan2(getplayerxspeed(0), getplayeryspeed(0)))-180)-180
  124.                         tmp_rot = 180-cc.rope.rot
  125.                         cc.rope.speed = math.min(cc.rope.rot-tmp_angle, 180-cc.rope.rot-tmp_angle)/90.0
  126.                         cc.rope.speed = cc.rope.speed*(math.sqrt((getplayerxspeed(0)^2)+(getplayeryspeed(0)^2)))/1.5
  127.                         
  128.                         -- Visual and audioel (yeah, that word might exist) appeal
  129.                         playsound(sfx_splatter5)
  130.                         -- Impact FX disabled by DC
  131.                         -- terrainalphaimage(gfx_blood25, cc.rope.stack[cc.rope.stack_top].x, cc.rope.stack[cc.rope.stack_top].y, 1.0, 200, 200, 200)
  132.                         
  133.                         -- // CHANGE BY DC: Disable rope with space (requires a timer)
  134.                         weapon_timer=15
  135.                         -- CHANGE BY DC //
  136.                         
  137.                         okay = 0
  138.                         break
  139.                     end
  140.                 end
  141.                 if okay == 0 then break end
  142.             end
  143.         end
  144.         
  145.         -- FOR MOUSE-AIMING:
  146.         --weapon_position = 0
  147.     end
  148.     
  149.     -- Rope is out
  150.     if weapon_mode == 1 then
  151.         cc.rope.rot = cc.rope.normangle(cc.rope.rot)
  152.         
  153.         -- Longer
  154.         if keydown(key_down) == 1 then
  155.             cc.rope.change_length(3)
  156.         -- Shorter
  157.         elseif keydown(key_up) == 1 then
  158.             cc.rope.change_length(-3)
  159.         end
  160.         
  161.         -- Turn left
  162.         if keydown(key_left) == 1 then
  163.             cc.rope.speed = cc.rope.speed + math.abs(math.cos(180-cc.rope.rot)*0.15) -- +0.08
  164.         end
  165.         
  166.         -- Turn right
  167.         if keydown(key_right) == 1 then
  168.             cc.rope.speed = cc.rope.speed - math.abs(math.cos(180-cc.rope.rot)*0.15) -- 0.08
  169.         end
  170.         
  171.         cc.rope.speed = cc.rope.speed+(0.15*cc.rope.sign(180-cc.rope.rot))
  172.         if math.abs(cc.rope.speed) > 5 then cc.rope.speed = 5*cc.rope.sign(cc.rope.speed) end
  173.         cc.rope.speed = cc.rope.speed*0.985
  174.         --if math.abs(cc.rope.speed) < 0.1 then cc.rope.speed = 0 end 
  175.         
  176.         tmp_sp = cc.rope.speed
  177.         if cc.rope.left > 150 then tmp_sp = tmp_sp*(150/cc.rope.left) end
  178.         tmp = cc.rope.precision_turn(tmp_sp)
  179.         if tmp == 1 then
  180.             cc.rope.speed = -cc.rope.speed
  181.         end
  182.         
  183.         playerposition(0, cc.rope.posplx(cc.rope.rot, cc.rope.left), cc.rope.posply(cc.rope.rot, cc.rope.left))
  184.         playerpush(0, 0, 0, 1)
  185.         
  186.         -- No more rope
  187.         -- // CHANGE BY DC: Disable rope with space (requires a timer)
  188.         -- if keydown(key_jump) == 1 then
  189.         if keydown(key_attack)==1 and weapon_timer<=0 then
  190.             weapon_timer=10
  191.         -- CHANGE BY DC //
  192.             playerpush(0, math.sin(math.rad(cc.rope.rot+(90*cc.rope.sign(cc.rope.rot-180))))*math.abs(cc.rope.speed)*1.5, -math.cos(math.rad(cc.rope.rot+(90*cc.rope.sign(cc.rope.rot-180))))*math.abs(cc.rope.speed)*1.5, 1)
  193.             playercontrol(1)
  194.             --useweapon(1)
  195.             weapon_mode = 0
  196.         end
  197.         
  198.         -- Disable Rope (Terrain Modification)
  199.         if terrainmodification()==1 then
  200.             weapon_timer=10
  201.             playerpush(0, math.sin(math.rad(cc.rope.rot+(90*cc.rope.sign(cc.rope.rot-180))))*math.abs(cc.rope.speed)*1.5, -math.cos(math.rad(cc.rope.rot+(90*cc.rope.sign(cc.rope.rot-180))))*math.abs(cc.rope.speed)*1.5, 1)
  202.             playercontrol(1)
  203.             weapon_mode = 0
  204.         end
  205.         
  206.         -- Time out
  207.         if getframesleft() < 5 then
  208.             weapon_mode = 3
  209.             playerpush(0, math.sin(math.rad(cc.rope.rot+(90*cc.rope.sign(cc.rope.rot-180))))*math.abs(cc.rope.speed)*1.5, -math.cos(math.rad(cc.rope.rot+(90*cc.rope.sign(cc.rope.rot-180))))*math.abs(cc.rope.speed)*1.5, 1)
  210.             endturn()
  211.         end
  212.     end
  213. end
  214.  
  215. -- Turning: positive degree for left, negative for right
  216. function cc.rope.precision_turn(degree)
  217.     tmp_rot = degree/3.0
  218.     tmp_col = 0
  219.     for i=0, 2, 1 do
  220.         col = cc.rope.turn(tmp_rot)
  221.         if col == 1 then break end
  222.     end
  223.     return col
  224. end
  225.  
  226. function cc.rope.turn(degree)
  227.     if degree == 0.0 then return 0 end
  228.     --if (cc.rope.rot > 315 and  degree > 0.0) then return 1 end
  229.     --if (cc.rope.rot < 45 and  degree < 0.0) then return 1 end
  230.     
  231.     old_top = cc.rope.stack_top
  232.     old_left = cc.rope.left
  233.     -- New vertices
  234.     repeat
  235.         okay = cc.rope.col(degree)
  236.         if okay == 1 then break end
  237.         if cc.rope.left < 1 then break end
  238.     until 1 == 2
  239.     if okay == 1 then
  240.         -- Player may not collide
  241.         if collision(colplayer, cc.rope.posplx(cc.rope.rot+degree, cc.rope.left), cc.rope.posply(cc.rope.rot+degree, cc.rope.left), 1, 1, 1, 0) == 0 then
  242.             cc.rope.rot = cc.rope.rot + degree
  243.             
  244.             -- maybe delete some points
  245.             if cc.rope.stack_top > 1 then
  246.                 repeat
  247.                     if degree > 0.0 then
  248.                         if (cc.rope.stack[cc.rope.stack_top].rot > cc.rope.rot-degree and cc.rope.stack[cc.rope.stack_top].rot <= cc.rope.rot) then
  249.                             cc.rope.left = cc.rope.left + cc.rope.stack[cc.rope.stack_top].used
  250.                             cc.rope.stack_top = cc.rope.stack_top - 1
  251.                         else
  252.                             break
  253.                         end
  254.                     else
  255.                         if (cc.rope.stack[cc.rope.stack_top].rot < cc.rope.rot-degree and cc.rope.stack[cc.rope.stack_top].rot >= cc.rope.rot) then
  256.                             cc.rope.left = cc.rope.left + cc.rope.stack[cc.rope.stack_top].used
  257.                             cc.rope.stack_top = cc.rope.stack_top - 1
  258.                         else
  259.                             break
  260.                         end
  261.                     end
  262.                 until cc.rope.stack_top == 1
  263.             end
  264.         else
  265.             cc.rope.stack_top = old_top
  266.             cc.rope.left = old_left
  267.             return 1
  268.         end
  269.     end
  270.     
  271.     return 0
  272. end
  273.  
  274. -- Change rope length, please just integers
  275. function cc.rope.change_length(len)
  276.     if len == 0.0 then return end
  277.     if (len > 0.0 and cc.rope.len >= cc.rope.max_len) then return end
  278.     if (len < 0.0 and cc.rope.left <= 1) then return end
  279.     
  280.     for i=1, math.abs(len), 1 do
  281.         if collision(colplayer, cc.rope.posplx(cc.rope.rot, cc.rope.left+(1*cc.rope.sign(len))), cc.rope.posply(cc.rope.rot, cc.rope.left+(1*cc.rope.sign(len))), 1, 1, 1, 0) == 0 then
  282.             cc.rope.len = cc.rope.len + (1*cc.rope.sign(len))
  283.             cc.rope.left = cc.rope.left + (1*cc.rope.sign(len))
  284.         else
  285.             break
  286.         end
  287.     end
  288. end
  289.  
  290. -- Collision check
  291. function cc.rope.col(dir)
  292.     go_x = math.sin(math.rad(cc.rope.rot+dir))
  293.     go_y = -math.cos(math.rad(cc.rope.rot+dir))
  294.     go_x_old = math.sin(math.rad(cc.rope.rot))
  295.     go_y_old = -math.cos(math.rad(cc.rope.rot))
  296.     okay = 1
  297.     
  298.     if cc.rope.left >= 2 then
  299.         tmp = cc.rope.left
  300.         
  301.         for i=3, tmp, 5 do
  302.             tmp_x = cc.rope.stack[cc.rope.stack_top].x+(go_x*i)
  303.             tmp_y = cc.rope.stack[cc.rope.stack_top].y+(go_y*i)
  304.             
  305.             if collision(col5x5, tmp_x, tmp_y, 1, 1, 1, 0) == 1 then
  306.                 for j=(i-2), i+2, 1 do
  307.                     if j > cc.rope.left then break end
  308.                     
  309.                     tmp_x = cc.rope.stack[cc.rope.stack_top].x+(go_x*j)
  310.                     tmp_y = cc.rope.stack[cc.rope.stack_top].y+(go_y*j)
  311.                     
  312.                     if collision(col5x5, tmp_x, tmp_y, 1, 1, 1, 0) == 1 then
  313.                         tmp_x = cc.rope.stack[cc.rope.stack_top].x+(go_x_old*j)
  314.                         tmp_y = cc.rope.stack[cc.rope.stack_top].y+(go_y_old*j)
  315.                         cc.rope.stack_push(tmp_x, tmp_y, j, cc.rope.normangle(cc.rope.rot))
  316.                         cc.rope.left = cc.rope.left - j
  317.                         okay = 0
  318.                         break
  319.                     end
  320.                 end
  321.             end
  322.             
  323.             if okay == 0 then break end
  324.         end
  325.     end
  326.     
  327.     return okay
  328. end
  329.  
  330.  
  331.  
  332. -- Some simple stack functions (stack, using an array)
  333. function cc.rope.stack_push(fx, fy, fu, fr)
  334.     cc.rope.stack_top = cc.rope.stack_top + 1
  335.     cc.rope.stack[cc.rope.stack_top] = {}
  336.     cc.rope.stack[cc.rope.stack_top].x = fx
  337.     cc.rope.stack[cc.rope.stack_top].y = fy
  338.     cc.rope.stack[cc.rope.stack_top].used = fu
  339.     cc.rope.stack[cc.rope.stack_top].rot = fr
  340. end
  341.  
  342. -- Get relative
  343. function cc.rope.getanglex(rot, len)
  344.     return math.sin(math.rad(rot))*len
  345. end
  346.  
  347. function cc.rope.getangley(rot, len)
  348.     return -math.cos(math.rad(rot))*len
  349. end
  350.  
  351. -- Position player
  352. function cc.rope.posplx(rot, len)
  353.     return cc.rope.stack[cc.rope.stack_top].x+cc.rope.getanglex(rot , len)
  354. end
  355.  
  356. function cc.rope.posply(rot, len)
  357.     return cc.rope.stack[cc.rope.stack_top].y+cc.rope.getangley(rot, len)
  358. end
  359.  
  360. -- Norm the angle
  361. function cc.rope.normangle(rot)
  362.     if rot < 0 then
  363.         rot = rot + 360
  364.         cc.rope.normangle(rot)
  365.     elseif rot > 360 then
  366.         rot = rot - 360
  367.         cc.rope.normangle(rot)
  368.     end
  369.     return rot
  370. end
  371.  
  372. -- Sign
  373. function cc.rope.sign(number)
  374.     if number < 0.0 then return -1 end
  375.     return 1
  376. end